<template>
	<view
		class="tab-list"
		:scroll-into-view="scrollIntoId"
		:class="{ sticky: isSticky }"
		:style="{ paddingTop: isSticky ? `${navbarHeight + statusBarHeight}px` : '' }"
		v-if="isSticky"
	>
		<view class="tabs" :class="{ flex }" v-if="tabs.length">
			<view
				v-for="(item, index) in tabs"
				:key="index"
				:id="`tab-${item.id}`"
				class="tab-item"
				:class="{ active: currentIndex === index }"
				@click.stop="handleTabClick(index)"
			>
				{{ item.name }}
			</view>
		</view>
	</view>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted } from "vue"
import useCommonStore from "@/store/common"
const { statusBarHeight, navbarHeight } = useCommonStore()
const emit = defineEmits(["update:modelValue"])

const props = defineProps({
	tabs: {
		type: Array,
		default: () => [],
	},
	scrollTop: {
		type: Number,
		default: 0,
	},
	flex: {
		type: Boolean,
		default: false,
	},
	modelValue: {
		type: Boolean,
		default: false,
	},
	offsetTop: {
		type: Number,
		default: 0,
	},
})
const originShow = props.modelValue
const isSticky = ref(props.modelValue)
const lastScrollTop = ref(0)
watch(
	() => props.scrollTop,
	(newVal: number) => {
		lastScrollTop.value = newVal
		if (newVal > statusBarHeight + navbarHeight) {
			isSticky.value = true
			handleScroll()
		} else {
			isSticky.value = originShow
		}
		emit("update:modelValue", isSticky.value)
	}
)

const currentIndex = ref(0)
const scrollIntoId = ref("")

const state = reactive({
	tabPositions: [],
})

const topHeight = statusBarHeight + navbarHeight + 100

const handleTabClick = (index) => {
	uni.pageScrollTo({
		scrollTop: state.tabPositions[index].top - topHeight,
		duration: 300, // 动画持续时间，单位 ms
	})
}

const handleScroll = () => {
	const currentScrollTop = lastScrollTop.value + topHeight
	let activeIndex = -1
	// console.log(currentScrollTop)
	// console.table(state.tabPositions)
	for (let i = 0; i < state.tabPositions.length; i++) {
		const tabPosition = state.tabPositions[i]
		if (currentScrollTop >= tabPosition.top && currentScrollTop < tabPosition.bottom) {
			activeIndex = i
			break
		}
	}
	// 如果找到一个有效索引，且索引有变化，则更新当前索引
	if (activeIndex !== -1 && currentIndex.value !== activeIndex) {
		currentIndex.value = activeIndex
	}
}

const calculateTabPositions = () => {
	return new Promise((resolve) => {
		const query = uni.createSelectorQuery()
		const offset = statusBarHeight + navbarHeight

		nextTick(() => {
			props.tabs.forEach((tab: any, index: number) => {
				query.select("#" + tab.id).boundingClientRect()
			})
			query.exec((res) => {
				state.tabPositions = res
					.map((rect: any, index: number) => ({
						index,
						top: rect?.top,
						bottom: rect?.bottom,
						height: rect?.height,
					}))
					.filter(Boolean)
				resolve(true)
			})
		})
	})
}
defineExpose({
	calculateTabPositions,
})
onMounted(() => {
	calculateTabPositions()
})

onUnmounted(() => {
	// 取消监听滚动事件
})
</script>

<style scoped lang="scss">
.sticky {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 3;
	background-color: #fff;
}
.tabs {
	height: 88rpx;
	display: -webkit-box;
	overflow-x: auto;
	overflow-y: hidden;
	font-size: 28rpx;
	color: rgba(0, 0, 0, 0.6);

	&.flex {
		display: flex;

		.tab-item {
			flex: 1;
			padding: 0;
		}
	}

	.tab-item {
		height: 100%;
		display: flex;
		align-items: center;
		justify-content: center;
		padding: 0 24rpx;
		min-width: 100rpx;
		position: relative;

		&.active {
			color: rgba(0, 0, 0, 0.9);
			font-weight: 600;
			&::after {
				position: absolute;
				content: "";
				width: 44rpx;
				height: 6rpx;
				bottom: 0;
				background: #fee038;
				border-radius: 6rpx;
			}
		}
	}
}
</style>
